package com.snail.sell.service;

import com.snail.sell.Exception.SellException;
import com.snail.sell.Exception.SellerAuthorizeException;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * @Author: XJL
 * @Description:
 * @Date: Create in 11:03 2017/12/24
 * @Modified By:
 **/
@Component
@Slf4j
public class RedisLock {

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 加锁
     * @param key
     * @param value 当前时间+超时时间
     * @return
     */
    public Boolean lock(String key,String value){
        if (redisTemplate.opsForValue().setIfAbsent(key,value)){
            return true;
        }

        //此段代码实在数据库操作发生异常时，而没有解锁，所以会设置一个超时时间，当超时时自动解锁，
        // 且保证只有一个线程获得改锁
        //假设以前的Value值currentValue=A，进来的线程Value=B
        String currentValue = redisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(currentValue)&&Long.parseLong(currentValue)<System.currentTimeMillis()){
            //当其中某个线程1执行该代码时，将自己的value=B设置进去并获得旧的value=A，
            String oldValue = redisTemplate.opsForValue().getAndSet(key,value);

            //线程1判断currentValue=A是否与自己获得的oldValue是否相当，如果相等获得该锁，
            // 当其他线程进来时，oldValue值已经被重新设置过
            if (!StringUtils.isEmpty(oldValue)&&currentValue.equals(oldValue)){
                return true;
            }
        }
        return false;
    }

    /**
     * 解锁
     * @param key
     * @param value
     */
    public void unLock(String key,String value){

       try {
           String currentValue = redisTemplate.opsForValue().get(key);
           //即该Value值为自己在加锁阶段的Value值时，进行解锁
           if (!StringUtils.isEmpty(currentValue)&&currentValue.equals(value)) {
               redisTemplate.opsForValue().getOperations().delete(key);

           }
       }catch (Exception e){
           log.error("【redis分布式锁】{}",e);
       }

    }

}
